package com.ruoyi.web.controller.pack;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.pack.domain.PackContainer;
import com.ruoyi.pack.domain.PackContainerOperationLog;
import com.ruoyi.pack.domain.PackTransferRecord;
import com.ruoyi.pack.domain.PackLocationLog;
import com.ruoyi.pack.domain.dto.PackContainerInventoryDTO;
import com.ruoyi.pack.domain.dto.PackContainerSummaryDto;

import com.ruoyi.pack.service.IPackContainerService;
import com.ruoyi.pack.service.IPackContainerOperationLogService;
import com.ruoyi.pack.service.IPackTransferRecordService;
import com.ruoyi.pack.service.IPackLocationLogService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.utils.SecurityUtils;
import com.github.pagehelper.PageHelper;

/**
 * 器具Controller
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@RestController
@RequestMapping("/pack/container")
public class PackContainerController extends BaseController
{
    @Autowired
    private IPackContainerService packContainerService;

    @Autowired
    private IPackContainerOperationLogService packContainerOperationLogService;

    @Autowired
    private IPackTransferRecordService packTransferRecordService;

    @Autowired
    private IPackLocationLogService packLocationLogService;

    /**
     * 查询器具列表
     */
    @PreAuthorize("@ss.hasPermi('pack:container:list')")
    @GetMapping("/list")
    public TableDataInfo list(PackContainer packContainer)
    {
        startPage();
        List<PackContainer> list = packContainerService.selectPackContainerList(packContainer);
        return getDataTable(list);
    }

    /**
     * 导出器具列表
     */
    @PreAuthorize("@ss.hasPermi('pack:container:export')")
    @Log(title = "器具", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, PackContainer packContainer)
    {
        List<PackContainer> list = packContainerService.selectPackContainerList(packContainer);
        ExcelUtil<PackContainer> util = new ExcelUtil<PackContainer>(PackContainer.class);
        util.exportExcel(response, list, "器具数据");
    }

    /**
     * 获取器具详细信息
     */
    @PreAuthorize("@ss.hasPermi('pack:container:query')")
    @GetMapping(value = "/{containerId}")
    public AjaxResult getInfo(@PathVariable("containerId") Long containerId)
    {
        return success(packContainerService.selectPackContainerByContainerId(containerId));
    }

    /**
     * 新增器具
     */
    @PreAuthorize("@ss.hasPermi('pack:container:add')")
    @Log(title = "器具", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody PackContainer packContainer)
    {
        // 校验器具编码唯一性
        if (!packContainerService.checkContainerCodeUnique(packContainer.getContainerCode()))
        {
            return error("新增器具'" + packContainer.getContainerCode() + "'失败，器具编码已存在");
        }
        
        return toAjax(packContainerService.insertPackContainer(packContainer));
    }

    /**
     * 修改器具
     */
    @PreAuthorize("@ss.hasPermi('pack:container:edit')")
    @Log(title = "器具", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody PackContainer packContainer)
    {
        return toAjax(packContainerService.updatePackContainer(packContainer));
    }

    /**
     * 删除器具
     */
    @PreAuthorize("@ss.hasPermi('pack:container:remove')")
    @Log(title = "器具", businessType = BusinessType.DELETE)
    @DeleteMapping("/{containerIds}")
    public AjaxResult remove(@PathVariable Long[] containerIds)
    {
        return toAjax(packContainerService.deletePackContainerByContainerIds(containerIds));
    }

    /**
     * 器具绑定定位器
     */
    @PreAuthorize("@ss.hasPermi('pack:container:bind')")
    @Log(title = "器具绑定定位器", businessType = BusinessType.UPDATE)
    @PostMapping("/{containerId}/bind-locator")
    public AjaxResult bindLocator(@PathVariable("containerId") Long containerId, @RequestBody BindLocatorRequest request)
    {
        // 校验绑定条件
        if (!packContainerService.checkCanBindLocator(containerId, request.getLocatorId()))
        {
            return error("绑定失败，器具或定位器状态不允许绑定");
        }
        
        return toAjax(packContainerService.bindLocator(containerId, request.getLocatorId()));
    }

    /**
     * 器具解绑定位器
     */
    @PreAuthorize("@ss.hasPermi('pack:container:unbind')")
    @Log(title = "器具解绑定位器", businessType = BusinessType.UPDATE)
    @PostMapping("/{containerId}/unbind-locator")
    public AjaxResult unbindLocator(@PathVariable("containerId") Long containerId)
    {
        return toAjax(packContainerService.unbindLocator(containerId));
    }

    /**
     * 器具批量绑定定位器
     */
    @PreAuthorize("@ss.hasPermi('pack:container:bind')")
    @Log(title = "器具批量绑定定位器", businessType = BusinessType.UPDATE)
    @PostMapping("/{containerId}/batch-bind-locators")
    public AjaxResult batchBindLocators(@PathVariable("containerId") Long containerId, @RequestBody BatchBindLocatorsRequest request)
    {
        if (request.getLocatorIds() == null || request.getLocatorIds().length == 0)
        {
            return error("请选择要绑定的定位器");
        }
        
        return toAjax(packContainerService.batchBindLocators(containerId, request.getLocatorIds()));
    }

    /**
     * 更新器具状态
     */
    @PreAuthorize("@ss.hasPermi('pack:container:status')")
    @Log(title = "更新器具状态", businessType = BusinessType.UPDATE)
    @PutMapping("/{containerId}/status")
    public AjaxResult updateStatus(@PathVariable("containerId") Long containerId, @RequestBody UpdateStatusRequest request)
    {
        return toAjax(packContainerService.updateContainerStatus(containerId, 
            request.getLocationStatus(), request.getBusinessStatus(), request.getPackingStatus()));
    }

    /**
     * 器具装箱
     */
    @PreAuthorize("@ss.hasPermi('pack:container:pack')")
    @Log(title = "器具装箱", businessType = BusinessType.UPDATE)
    @PostMapping("/{containerId}/pack")
    public AjaxResult packContainer(@PathVariable("containerId") Long containerId, @RequestBody PackContainerRequest request)
    {
        // 校验装箱条件
        if (!packContainerService.checkContainerOperationAllowed(containerId, "pack"))
        {
            return error("装箱失败，器具状态不允许装箱");
        }
        
        return toAjax(packContainerService.packContainer(containerId, request.getProjectId(), 
            request.getMaterialCode(), request.getMaterialName(), request.getMaterialQuantity(), request.getLiningScheme()));
    }

    /**
     * 器具拆箱
     */
    @PreAuthorize("@ss.hasPermi('pack:container:unpack')")
    @Log(title = "器具拆箱", businessType = BusinessType.UPDATE)
    @PostMapping("/{containerId}/unpack")
    public AjaxResult unpackContainer(@PathVariable("containerId") Long containerId)
    {
        // 校验拆箱条件
        if (!packContainerService.checkContainerOperationAllowed(containerId, "unpack"))
        {
            return error("拆箱失败，器具状态不允许拆箱");
        }
        
        return toAjax(packContainerService.unpackContainer(containerId));
    }

    /**
     * 库存统计查询
     */
    @PreAuthorize("@ss.hasPermi('pack:container:inventory')")
    @GetMapping("/inventory/statistics")
    public TableDataInfo inventoryStatistics(PackContainer packContainer)
    {
        startPage();
        List<PackContainerInventoryDTO> list = packContainerService.selectInventoryStatistics(packContainer);
        return getDataTable(list);
    }

    /**
     * 根据器具编码查询器具
     */
    @PreAuthorize("@ss.hasPermi('pack:container:query')")
    @GetMapping("/code/{containerCode}")
    public AjaxResult getByCode(@PathVariable("containerCode") String containerCode)
    {
        return success(packContainerService.selectPackContainerByContainerCode(containerCode));
    }

    /**
     * 校验器具编码
     */
    @GetMapping("/checkContainerCodeUnique")
    public AjaxResult checkContainerCodeUnique(String containerCode)
    {
        boolean isUnique = packContainerService.checkContainerCodeUnique(containerCode);
        return success(isUnique);
    }

    /**
     * 查询器具操作记录列表
     */
    @PreAuthorize("@ss.hasPermi('pack:container:query')")
    @GetMapping("/operation/list")
    public TableDataInfo operationList(PackContainerOperationLog packContainerOperationLog)
    {
        startPage();
        List<PackContainerOperationLog> list = packContainerOperationLogService.selectPackContainerOperationLogList(packContainerOperationLog);
        return getDataTable(list);
    }

    /**
     * 查询器具移库记录列表
     */
    @PreAuthorize("@ss.hasPermi('pack:container:query')")
    @GetMapping("/transfer/list")
    public TableDataInfo transferList(PackTransferRecord packTransferRecord)
    {
        startPage();
        List<PackTransferRecord> list = packTransferRecordService.selectPackTransferRecordList(packTransferRecord);
        return getDataTable(list);
    }

    /**
     * 查询器具定位日志列表
     */
    @PreAuthorize("@ss.hasPermi('pack:container:query')")
    @GetMapping("/location/list")
    public TableDataInfo locationList(PackLocationLog packLocationLog)
    {
        startPage();
        List<PackLocationLog> list = packLocationLogService.selectPackLocationLogList(packLocationLog);
        return getDataTable(list);
    }

    /**
     * 获取器具列表用于定位器选择（简化权限）
     */
    @PreAuthorize("@ss.hasPermi('pack:locator:list')")
    @GetMapping("/list-for-locator")
    public TableDataInfo listForLocator(PackContainer packContainer)
    {
        // 获取分页参数
        PageDomain pageDomain = TableSupport.buildPageRequest();
        
        // 查询数据
        List<PackContainer> list = packContainerService.selectPackContainerList(packContainer);
        
        // 手动实现分页逻辑
        int pageNum = pageDomain.getPageNum();
        int pageSize = pageDomain.getPageSize();
        int total = list.size();
        
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);
        
        List<PackContainer> pageList = new ArrayList<>();
        if (startIndex < total) {
            pageList = list.subList(startIndex, endIndex);
        }
        
        TableDataInfo result = new TableDataInfo();
        result.setCode(200);
        result.setMsg("查询成功");
        result.setRows(pageList);
        result.setTotal(total);
        
        return result;
    }

    /**
     * 绑定定位器请求体
     */
    public static class BindLocatorRequest {
        private Long locatorId;

        public Long getLocatorId() {
            return locatorId;
        }

        public void setLocatorId(Long locatorId) {
            this.locatorId = locatorId;
        }
    }

    /**
     * 更新状态请求体
     */
    public static class UpdateStatusRequest {
        private String locationStatus;
        private String businessStatus;
        private String packingStatus;

        public String getLocationStatus() {
            return locationStatus;
        }

        public void setLocationStatus(String locationStatus) {
            this.locationStatus = locationStatus;
        }

        public String getBusinessStatus() {
            return businessStatus;
        }

        public void setBusinessStatus(String businessStatus) {
            this.businessStatus = businessStatus;
        }

        public String getPackingStatus() {
            return packingStatus;
        }

        public void setPackingStatus(String packingStatus) {
            this.packingStatus = packingStatus;
        }
    }

    /**
     * 装箱请求体
     */
    public static class PackContainerRequest {
        private Long projectId;
        private String materialCode;
        private String materialName;
        private String materialQuantity;
        private String liningScheme;

        public Long getProjectId() {
            return projectId;
        }

        public void setProjectId(Long projectId) {
            this.projectId = projectId;
        }

        public String getMaterialCode() {
            return materialCode;
        }

        public void setMaterialCode(String materialCode) {
            this.materialCode = materialCode;
        }

        public String getMaterialName() {
            return materialName;
        }

        public void setMaterialName(String materialName) {
            this.materialName = materialName;
        }

        public String getMaterialQuantity() {
            return materialQuantity;
        }

        public void setMaterialQuantity(String materialQuantity) {
            this.materialQuantity = materialQuantity;
        }

        public String getLiningScheme() {
            return liningScheme;
        }

        public void setLiningScheme(String liningScheme) {
            this.liningScheme = liningScheme;
        }
    }

    /**
     * 批量绑定定位器请求体
     */
    public static class BatchBindLocatorsRequest {
        private Long[] locatorIds;

        public Long[] getLocatorIds() {
            return locatorIds;
        }

        public void setLocatorIds(Long[] locatorIds) {
            this.locatorIds = locatorIds;
        }
    }

    /**
     * 器具汇总统计查询
     */
    @PreAuthorize("@ss.hasPermi('pack:container:summary')")
    @GetMapping("/summary")
    public TableDataInfo summary(PackContainer packContainer)
    {
        startPage();
        // 设置公司权限过滤 - 只查询当前用户所属公司的器具
        // 注意：这里需要根据实际的用户-公司关联关系来设置companyId
        // 如果用户表中有companyId字段，可以通过SecurityUtils.getLoginUser().getUser().getCompanyId()获取
        // 这里暂时注释，需要根据实际的用户表结构来实现
        // packContainer.setCompanyId(getCurrentUserCompanyId());

        List<PackContainerSummaryDto> list = packContainerService.selectContainerSummary(packContainer);
        return getDataTable(list);
    }

    /**
     * 获取器具汇总详情列表
     */
    @PreAuthorize("@ss.hasPermi('pack:container:summary')")
    @GetMapping("/summary/detail")
    public TableDataInfo summaryDetail(PackContainer packContainer)
    {
        startPage();
        // 设置公司权限过滤 - 只查询当前用户所属公司的器具
        // 注意：这里需要根据实际的用户-公司关联关系来设置companyId
        // packContainer.setCompanyId(getCurrentUserCompanyId());

        List<PackContainer> list = packContainerService.selectContainerSummaryDetail(packContainer);
        return getDataTable(list);
    }

    /**
     * 获取器具移动记录
     */
    @PreAuthorize("@ss.hasPermi('pack:container:summary')")
    @GetMapping("/{containerId}/transfer-records")
    public TableDataInfo transferRecords(@PathVariable("containerId") String containerId, PackTransferRecord packTransferRecord)
    {
        startPage();
        List<PackTransferRecord> list;

        if ("summary".equals(containerId)) {
            // 汇总查询的移动记录
            list = packTransferRecordService.selectTransferRecordsBySummaryCondition(packTransferRecord);
        } else {
            // 单个器具的移动记录
            packTransferRecord.setContainerId(Long.valueOf(containerId));
            list = packTransferRecordService.selectPackTransferRecordListByContainerId(Long.valueOf(containerId));
        }

        return getDataTable(list);
    }

    /**
     * 导出器具汇总统计数据
     */
    @PreAuthorize("@ss.hasPermi('pack:container:summary')")
    @Log(title = "器具汇总统计", businessType = BusinessType.EXPORT)
    @PostMapping("/summary/export")
    public void exportSummary(HttpServletResponse response, PackContainer packContainer)
    {
        List<PackContainerSummaryDto> list = packContainerService.selectContainerSummary(packContainer);
        ExcelUtil<PackContainerSummaryDto> util = new ExcelUtil<PackContainerSummaryDto>(PackContainerSummaryDto.class);
        util.exportExcel(response, list, "器具汇总统计数据");
    }
}